'use strict'

import {app, protocol, BrowserWindow, Menu, dialog, ipcMain, nativeImage, shell, ipcRenderer} from 'electron'
import {Logger} from "@/utils/logUtils";
import fs from "fs";

import {IniUtils} from '@/utils/iniUtils'
import {createProtocol} from "vue-cli-plugin-electron-builder/lib";


const log4js = require('log4js');
const path = require('path');


// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([
  {scheme: 'app', privileges: {secure: true, standard: true}}
])


// 获取 EXE 文件所在目录
const exeDir = path.dirname(process.execPath);
// 定义 data 目录
const dataDir = path.join(exeDir, 'data');

IniUtils.set("window.default.project.path", `${dataDir}/project`)

// 确保 data 目录存在
if (!fs.existsSync(dataDir)) {
  fs.mkdirSync(dataDir);
}
app.setPath("userData", dataDir)

// 配置log4js
log4js.configure({
  appenders: {
    errorFile: {
      type: 'file',
      filename: app.getPath('userData') + '/logs/error.log',
      layout: {type: 'pattern', pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c - %m%n'}

    },
    warnFile: {
      type: 'file',
      filename: app.getPath('userData') + '/logs/warn.log',
      layout: {type: 'pattern', pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c - %m%n'}
    },
    debugFile: {
      type: 'file',
      filename: app.getPath('userData') + '/logs/debug.log',
      layout: {type: 'pattern', pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c - %m%n'}
    },
    infoFile: {
      type: 'file',
      filename: app.getPath('userData') + '/logs/info.log',
      layout: {type: 'pattern', pattern: '%d{yyyy-MM-dd hh:mm:ss.SSS} %p %c - %m%n'}
    },
  },
  categories: {
    error: {appenders: ['errorFile'], level: 'error'},
    warn: {appenders: ['warnFile'], level: 'warn'},
    debug: {appenders: ['debugFile'], level: 'debug'},
    info: {appenders: ['infoFile'], level: 'info'},
    default: {appenders: ['infoFile'], level: 'info'}, // 这个default将处理所有未被上面分类捕获的日志
  }
});


let activeWin

// 打开文件夹标记
let folderFlag = false
// 未做功能提示标记
let messageFlag = false
// 打开新建项目窗口标记
let projectFlag  = false


// 创建窗口
async function createWindow() {

  if (parseInt(IniUtils.get('window.current.count')) === parseInt(IniUtils.get('window.max.count'))) {
    if (isCanBeep()) {
      return
    }
    messageFlag = true
    await dialog.showMessageBox({
      type: 'error',
      title: '警告',
      message: '您已经超过最大窗口限制',
    });
    messageFlag = false
    return
  }


  // Create the browser window.
  const win = new BrowserWindow({
    width: parseInt(IniUtils.get('window.default.width')),
    height: parseInt(IniUtils.get('window.default.height')),
    icon: IniUtils.get('window.default.icon'),
    webPreferences: {
      // webviewTag: true,
      enableRemoteModule: true,
      nodeIntegration: true,
      contextIsolation: false
    }
  })
  IniUtils.set('window.current.count', parseInt(IniUtils.get('window.current.count')) + 1)
  let activeWin = win;

  function isCanBeep() {
    if (folderFlag || messageFlag || projectFlag) {
      blurAndBee()
      return true
    }
    return false
  }

  //  获取焦点事件
  win.on('focus', () => {
    isCanBeep()
  });


  // 准备展示事件
  win.once('ready-to-show', () => {
    if (IniUtils.get('window.lastest.project.path')) {
      win.webContents.send('folder-opened', IniUtils.get('window.lastest.project.path'));
      IniUtils.set('window.lastest.project.name', IniUtils.get('window.lastest.project.name'));
      IniUtils.set('window.lastest.project.path', IniUtils.get('window.lastest.project.path'));
    }
  });

  // 取消焦点并警告
  function blurAndBee() {
    // 创建一个空的图像实例，仅用于触发声音播放
    const emptyImage = nativeImage.createFromBuffer(Buffer.from([]));
    win.blur();
    // 使用 shell.beep() 来播放警告声音
    shell.beep();
  }


  if (process.env.WEBPACK_DEV_SERVER_URL) {
    // Load the url of the dev server if in development mode
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
    if (!process.env.IS_TEST) win.webContents.openDevTools()
  } else {
    createProtocol('app')
    // Load the index.html when not in development
    win.loadURL('app://./index.html')
  }

  // win.loadFile('bundled/index.html');
  win.setTitle(IniUtils.get('window.lastest.project.name') || IniUtils.get('window.init.name'));

  win.webContents.on('page-title-updated', (event, title) => {
    win.setTitle(IniUtils.get('window.lastest.project.name') || IniUtils.get('window.init.name'));
  });


  // 创建菜单
  const template = [
    {
      label: '文件',
      submenu: [
        {
          label: '打开项目',
          click: () => {
            if (folderFlag) {
              blurAndBee()
              return;
            }
            folderFlag = true
            const filePaths = dialog.showOpenDialogSync({
              properties: ['openDirectory']
            });
            folderFlag = false
            if (filePaths && filePaths.length > 0) {
              const folderPath = filePaths[0].replace(/\\/g, '/');
              const projectName = folderPath.substring(folderPath.lastIndexOf('/') + 1);
              const currentTitle = win.getTitle();
              if (currentTitle === IniUtils.get('window.init.name') || currentTitle !== projectName) {
                IniUtils.set('window.lastest.project.name', projectName);
                IniUtils.set('window.lastest.project.path', folderPath);
                win.webContents.send('folder-opened', folderPath);
                win.setTitle(projectName);
              }
            }
          }
        },
        {
          label: '新建窗口(合并到打开项目)',
          click: () => {
            createWindow()
          }
        },
        {
          label: '新建项目',
          click: async () => {
            if (isCanBeep()) {
              return
            }
            win.webContents.send("new-project-open")
          }
        },
        {
          label: '导入',
          click: async () => {
            if (isCanBeep()) {
              return
            }
            messageFlag = true
            await dialog.showMessageBox({
              type: 'info',
              title: '功能提示',
              message: '有待商榷。',
            });
            messageFlag = false
          }
        },
      ]
    }, {
      label: '编辑', submenu: [{
        label: '撤销', accelerator: 'CmdOrCtrl+Z', role: 'undo'
      }, {
        label: '重做', accelerator: 'Shift+CmdOrCtrl+Z', role: 'redo'
      }, {type: 'separator'}, {
        label: '剪切', accelerator: 'CmdOrCtrl+X', role: 'cut'
      }, {
        label: '复制', accelerator: 'CmdOrCtrl+C', role: 'copy'
      }, {
        label: '粘贴', accelerator: 'CmdOrCtrl+V', role: 'paste'
      }, {
        label: '全选', accelerator: 'CmdOrCtrl+A', role: 'selectAll'
      }]
    }, {
      label: '工具', submenu: [{
        label: '新建地图',
        click: async () => {
          if (isCanBeep()) {
            return
          }
          messageFlag = true
          await dialog.showMessageBox({
            type: 'info',
            title: '功能提示',
            message: '此功能正在开发中，请稍后再试。',
          });
          messageFlag = false
        }
      }, {
        label: '新建图标',
        click: async () => {
          if (isCanBeep()) {
            return
          }

          messageFlag = true
          await dialog.showMessageBox({
            type: 'info',
            title: '功能提示',
            message: '此功能正在开发中，请稍后再试。',
          });
          messageFlag = false
        }
      }]
    },
    , {
      label: '帮助',
      click: async () => {
        if (isCanBeep()) {
          return
        }

        messageFlag = true
        await dialog.showMessageBox({
          type: 'info',
          title: '功能提示',
          message: '此功能正在开发中，请稍后再试。',
        });
        messageFlag = false
      }
    }];
  const menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);


  // 日志事件
  ipcMain.on('log4js:trace', (event, args) => {
    Logger.trace(args.category, args.message)
  });
  ipcMain.on('log4js:debug', (event, args) => {
    Logger.debug(args.category, args.message)
  });
  ipcMain.on('log4js:info', (event, args) => {
    Logger.info(args.category, args.message)
  });
  ipcMain.on('log4js:warn', (event, args) => {
    Logger.warn(args.category, args.message)
  });
  ipcMain.on('log4js:error', (event, args) => {
    Logger.error(args.category, args.message)
  });
  ipcMain.on('log4js:fatal', (event, args) => {
    Logger.fatal(args.category, args.message)
  });
  ipcMain.on('log4js:mark', (event, args) => {
    Logger.mark(args.category, args.message)
  });

  ipcMain.on('open:folder', (event, args) => {

  });

  ipcMain.on("onChoicePath", (event, args) => {
    if (folderFlag) {
      blurAndBee()
      return;
    }
    folderFlag = true
    dialog.showOpenDialog({
      properties: ['openDirectory']
    }).then(result => {
      folderFlag = false
      if (!result.canceled) {
        event.sender.send("onChoicePath", result.filePaths[0])
      }
    })
  })


  ipcMain.on("new-project", (event, args) => {
    projectFlag =args
  })

}


// Quit when all windows are closed.
app.on('window-all-closed', () => {
  // On macOS it is common for applications and their menu bar
  // to stay active until the user quits explicitly with Cmd + Q
  // todo 添加逻辑
  // 当前打开窗口数量 - 1
  // 设置关闭的窗口的标题和路径是我最后一次打开的
  if (process.platform !== 'darwin') {

    app.quit()
  }
})

app.on('activate', () => {
  // On macOS it's common to re-create a window in the app when the
  // dock icon is clicked and there are no other windows open.
  if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.whenReady().then(createWindow);


